package top.csmcool.musicapi.config;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.*;

/**
 * @Description
 * @Author shizhe
 * @Date 2024/7/17
 */

@Configuration
@EnableAsync
@Data
public class ExecutorConfig {

    @Value("${async.executor.thread.core_pool_size:2}")
    private int corePoolSize;

    @Value("${async.executor.thread.max_pool_size:5}")
    private int maxPoolSize;

    @Value("${async.executor.thread.queue_capacity:20}")
    private int queueCapacity;

    @Value("${async.executor.thread.name.prefix:test}")
    private String namePrefix;

    @Value("${async.executor.thread.keep_alive_time:3}")
    private long keepAliveTime;

    // ThreadPoolExecutor 使用自定义线程池
    @Bean
    public ThreadPoolExecutor threadPoolExecutor(){
        CustomThreadFactory customThreadFactory = new CustomThreadFactory(namePrefix);
        return new ThreadPoolExecutor(
                corePoolSize,
                maxPoolSize,//请求处理大时，可以开放的最大工作数
                keepAliveTime,
                TimeUnit.SECONDS,//存活时间单位
                new LinkedBlockingDeque<>(queueCapacity),
                customThreadFactory,
                new RejectedExecutionHandler() {    // 使用CallerRunsPolicy拒绝策略
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                        if (!executor.isShutdown()) {
                            r.run();    // 在调用者线程中运行任务
                        }
                    }
                });
    }


    @Bean(name = "asyncServiceExecutor")
    public ThreadPoolTaskExecutor asyncServiceExecutor(){
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
        threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
        threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
        threadPoolTaskExecutor.setKeepAliveSeconds(3);
        threadPoolTaskExecutor.setThreadNamePrefix(namePrefix);
        // rejection-policy：当pool已经达到max size的时候，如何处理新任务
        // CALLER_RUNS：不在新线程中执行任务，而是由调用者所在的线程来执行
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        //加载
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
}
